package cn.edu.gzgs.service.impl;

import cn.edu.gzgs.common.PageResult;
import cn.edu.gzgs.dto.DeptDTO;
import cn.edu.gzgs.dto.DeptPageQueryDTO;
import cn.edu.gzgs.entity.Dept;
import cn.edu.gzgs.entity.User;
import cn.edu.gzgs.entity.Title;
import cn.edu.gzgs.entity.Position;
import cn.edu.gzgs.exception.BusinessException;
import cn.edu.gzgs.exception.DeletionNotAllowedException;
import cn.edu.gzgs.mapper.DeptMapper;
import cn.edu.gzgs.mapper.UserMapper;
import cn.edu.gzgs.service.DeptService;
import cn.edu.gzgs.service.UserService;
import cn.edu.gzgs.vo.DeptUserVO;
import cn.edu.gzgs.vo.DeptVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 部门业务逻辑层实现
 *
 * @author Zyf
 * @since 2024-05-28
 */
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserService userService;

    /**
     * 新增部门
     *
     * @param deptDTO 部门数据传输对象
     */
    @Override
    public void saveDept(DeptDTO deptDTO) {
        // 部门名称唯一性校验
        validateDeptNameUnique(deptDTO.getName(), null);

        Dept dept = new Dept();
        BeanUtils.copyProperties(deptDTO, dept);
        // createdTime 和 updatedTime 由 MyBatis-Plus 自动填充
        deptMapper.insert(dept);
    }

    /**
     * 根据ID删除部门
     *
     * @param id 部门ID
     */
    @Override
    public void deleteById(Long id) {
        // 1. 检查是否存在子部门
        LambdaQueryWrapper<Dept> deptWrapper = new LambdaQueryWrapper<>();
        deptWrapper.eq(Dept::getParentId, id);
        if (deptMapper.selectCount(deptWrapper) > 0) {
            throw new DeletionNotAllowedException("该部门下存在子部门，不允许删除");
        }

        // 2. 检查部门下是否有用户
        LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(User::getDeptId, id);
        if (userMapper.selectCount(userWrapper) > 0) {
            throw new DeletionNotAllowedException("该部门下存在用户，不允许删除");
        }

        deptMapper.deleteById(id);
    }

    /**
     * 修改部门信息
     *
     * @param deptDTO 部门数据传输对象
     */
    @Override
    public void updateDept(DeptDTO deptDTO) {
        // 部门名称唯一性校验
        validateDeptNameUnique(deptDTO.getName(), deptDTO.getId());

        Dept dept = new Dept();
        BeanUtils.copyProperties(deptDTO, dept);
        // updatedTime 由 MyBatis-Plus 自动填充
        deptMapper.updateById(dept);
    }

    /**
     * 根据ID查询部门
     *
     * @param id 部门ID
     * @return Dept 部门实体
     */
    // @Override
    // public Dept getById(Long id) {
    //     return deptMapper.selectById(id);
    // }

    /**
     * 分页查询部门
     *
     * @param deptPageQueryDTO 部门分页查询参数
     * @return PageResult 分页结果
     */
    @Override
    public PageResult<DeptVO> pageQuery(DeptPageQueryDTO deptPageQueryDTO) {
        // 构造分页构造器
        Page<Dept> page = Page.of(deptPageQueryDTO.getPage(), deptPageQueryDTO.getPageSize());

        // 构造查询条件
        LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(deptPageQueryDTO.getName()), Dept::getName, deptPageQueryDTO.getName());
        queryWrapper.eq(deptPageQueryDTO.getType() != null, Dept::getType, deptPageQueryDTO.getType());
        queryWrapper.orderByDesc(Dept::getUpdatedTime);

        // 执行查询
        Page<Dept> resultPage = deptMapper.selectPage(page, queryWrapper);

        // 封装VO并返回
        List<DeptVO> deptVOList = resultPage.getRecords().stream().map(dept -> {
            DeptVO deptVO = new DeptVO();
            BeanUtils.copyProperties(dept, deptVO);
            return deptVO;
        }).collect(Collectors.toList());

        return new PageResult<>(resultPage.getTotal(), deptVOList);
    }

    /**
     * 根据部门ID查询其下的所有用户
     *
     * @param deptId 部门ID
     * @return 用户列表
     */
    @Override
    public List<User> getUsersByDeptId(Long deptId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDeptId, deptId);
        return userMapper.selectList(queryWrapper);
    }

    @Override
    public List<DeptUserVO> getDeptUsersByDeptId(Long deptId) {
        // 1. 获取部门下的所有用户实体
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDeptId, deptId);
        List<User> users = userMapper.selectList(queryWrapper);

        if (users.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 2. 将 User 实体列表转换为 DeptUserVO 列表
        return users.stream().map(user -> {
            DeptUserVO vo = new DeptUserVO();
            vo.setId(user.getId());
            vo.setName(user.getName());
            vo.setUserNo(user.getUserNo());

            // 3. 利用 UserService 获取关联信息来填充主要职称和岗位
            //    这里简化处理，取第一个作为"主要"信息
            List<Title> titles = userService.getTitlesByUserId(user.getId());
            if (!titles.isEmpty()) {
                vo.setMainTitle(titles.get(0).getName());
            }

            List<Position> positions = userService.getPositionsByUserId(user.getId());
            if (!positions.isEmpty()) {
                vo.setMainPosition(positions.get(0).getName());
            }
            
            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 获取所有部门列表
     *
     * @return 部门列表
     */
    @Override
    public List<DeptVO> listAll() {
        return list().stream().map(dept -> {
            DeptVO deptVO = new DeptVO();
            BeanUtils.copyProperties(dept, deptVO);
            return deptVO;
        }).collect(Collectors.toList());
    }

    /**
     * 校验部门名称是否唯一
     *
     * @param name 部门名称
     * @param id   部门ID（修改时传入，新增时为null）
     */
    private void validateDeptNameUnique(String name, Long id) {
        LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Dept::getName, name);
        if (id != null) {
            queryWrapper.ne(Dept::getId, id); // 排除自身
        }
        if (deptMapper.selectCount(queryWrapper) > 0) {
            throw new BusinessException("部门名称已存在");
        }
    }
} 